package xj.graph2d.app.prop;

import java.util.Comparator;

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

import xj.graph2d.table.FeatureTable;
import xj.graph2d.table.FeatureTableEntry;
import xj.model.uml.BasicModelElement;
import xj.model.uml.SuperType;
import xj.model.uml.SuperType.Kind;

public class UMLSuperTypeEntry implements FeatureTableEntry {

  // position of each column
  public static final int NAME_COLUMN = 0;

  public static final int KIND_COLUMN = 1;

  public static final int DELETE_COLUMN = 2;

  public static final String[] columnNames = { "Super Type Name", "Kind", "Delete", };

  public static final String[] columnTips = { 
    "Name of the super types",
    "Kind of the super types",
    "Delete the marked super types", };

  public static final Comparator[] comparators = {
    new FeatureEntryComparator(NAME_COLUMN), null, null, };
  
  public static TableCellEditor[] editors = new TableCellEditor[3];

  static { 
    JComboBox kindEditor = new JComboBox();
    kindEditor.addItem(Kind.Generalization); 
    kindEditor.addItem(Kind.Realization); 
    editors[KIND_COLUMN] = new DefaultCellEditor(kindEditor);
  }

  public static TableCellRenderer[] renderers = { null, null,
      new FeatureTable.GrayBooleanRenderer(), // for Delete
  };

  public static final int[] columnWidths = { 80, 30, 20, };

  public UMLSuperTypeEntry(String name, Kind kind) {
    this.name = name;
    this.kind = kind;
  }

  public UMLSuperTypeEntry(SuperType stype) {
    if (stype != null) { 
      name = stype.getName();
      kind = stype.getKind();
      if (kind == null || kind == Kind.Default) { 
	kind = Kind.Generalization;
      }
    }
  }

  public int getColumnCount() {
    return columnNames.length;
  }

  public String getColumnName(int col) {
    if (col >= 0 && col < columnNames.length) {
      return columnNames[col];
    }
    return null;
  }

  public Object getColumnValue(int col) {
    if (col >= 0 && col < columnNames.length) {
      switch (col) {
      case NAME_COLUMN:
	return name;
      case KIND_COLUMN:
	return kind;
      case DELETE_COLUMN:
	return deleted;
      }
    }
    return null;
  }

  public void setColumnValue(int col, Object value) {
    if (col >= 0 && col < columnNames.length) {
      switch (col) {
      case NAME_COLUMN:
	if (value != null) {
	  name = value.toString();
	} else {
	  name = null;
	}
	break;
      case KIND_COLUMN:
	kind = (Kind) value; 
	break;
      case DELETE_COLUMN:
	if (value instanceof Boolean) {
	  deleted = ((Boolean) value).booleanValue();
	}
	break;
      }
    }
  }

  public String getColumnTip(int col) {
    if (col >= 0 && col < columnTips.length) {
      return columnTips[col];
    }
    return null;
  }

  public Class getColumnClass(int col) {
    switch (col) {
    case NAME_COLUMN:
      return String.class;
    case KIND_COLUMN:
      return Kind.class;
    case DELETE_COLUMN:
      return Boolean.class;
    default:
      return String.class;
    }
  }

  public Comparator getColumnComparator(int col) {
    if (col >= 0 && col < comparators.length) {
      return comparators[col];
    }
    return null;
  }

  public TableCellEditor getColumnEditor(int col) {
    if (col >= 0 && col < editors.length) {
      return editors[col];
    }
    return null;
  }

  public boolean isColumnEditable(int col) {
    if (editable && col >= 0 && col < columnNames.length) {
      return editable;
    }
    return false;
  }

  public TableCellRenderer getColumnRenderer(int col) {
    if (col >= 0 && col < renderers.length) {
      return renderers[col];
    }
    return null;
  }

  public int getColumnWidth(int col) {
    if (col >= 0 && col < columnWidths.length) {
      return columnWidths[col];
    }
    return -1;
  }

  public String getName() {
    return name;
  }

  public SuperType.Kind getKind() {
    return kind;
  }

  public boolean isDeleted() {
    return deleted;
  }

  public boolean isEditable() {
    return editable;
  }

  public void setEditable(boolean e) {
    editable = e;
  }

  public BasicModelElement getModelElement() {
    return null;
  }

  protected String name;

  protected SuperType.Kind kind;

  protected boolean deleted = false;

  protected boolean editable = true;

  static public class FeatureEntryComparator implements Comparator {

    public FeatureEntryComparator(int col) {
      this.col = col;
    }

    public int compare(Object o1, Object o2) {
      if (o1 instanceof UMLSuperTypeEntry && o2 instanceof UMLSuperTypeEntry) {
	UMLSuperTypeEntry e1 = (UMLSuperTypeEntry) o1;
	UMLSuperTypeEntry e2 = (UMLSuperTypeEntry) o2;
	Object v1 = e1.getColumnValue(col);
	Object v2 = e2.getColumnValue(col);
	if (v1 != null && v2 != null) {
	  return ((String) v1).compareTo((String) v2);
	}
      }
      return 0;
    }

    protected int col;
  }

}
